 /************************************************************************************************************
 * @attention
 *
 * Firmware Disclaimer Information
 *
 * 1. The customer hereby acknowledges and agrees that the program technical documentation, including the
 *    code, which is supplied by Holtek Semiconductor Inc., (hereinafter referred to as "HOLTEK") is the
 *    proprietary and confidential intellectual property of HOLTEK, and is protected by copyright law and
 *    other intellectual property laws.
 *
 * 2. The customer hereby acknowledges and agrees that the program technical documentation, including the
 *    code, is confidential information belonging to HOLTEK, and must not be disclosed to any third parties
 *    other than HOLTEK and the customer.
 *
 * 3. The program technical documentation, including the code, is provided "as is" and for customer reference
 *    only. After delivery by HOLTEK, the customer shall use the program technical documentation, including
 *    the code, at their own risk. HOLTEK disclaims any expressed, implied or statutory warranties, including
 *    the warranties of merchantability, satisfactory quality and fitness for a particular purpose.
 *
 * <h2><center>Copyright (C) Holtek Semiconductor Inc. All rights reserved</center></h2>
 ************************************************************************************************************/
//Generated by HT32CodeConfig V1.0.2 Build 230411
//-----------------------------------------------------------------------------
#include "ht32.h"
#include "GPIO.h"
#include "USART1.h"
#include "TLV.h"

typedef struct userdata
{
	int temperature;
	int year;
	char month;
	char day;
	char hour;
	char minute;
} userdata;

#define USER_TYPE_1 0x01

extern ring_buffer_t rx_buf;
extern ring_buffer_t tx_buf;

//#define led1_off() GPIO_SetOutBits(OUT_PC14_GPIO_PORT, OUT_PC14_GPIO_PIN)
//#define led1_on()  GPIO_ClearOutBits(OUT_PC14_GPIO_PORT, OUT_PC14_GPIO_PIN)
//#define led2_off() GPIO_SetOutBits(OUT_PC15_GPIO_PORT, OUT_PC15_GPIO_PIN)
//#define led2_on()  GPIO_ClearOutBits(OUT_PC15_GPIO_PORT, OUT_PC15_GPIO_PIN)

void UART_MainRoutine(void)
{
	char tmp;
	tlv_head_t packet_head;
	uint16_t crc16, buf_len;
	uint8_t crc16_l, crc16_h;
	userdata RxUserdata;
	
	if ( ring_buffer_is_empty(&rx_buf) )	return ;
	buf_len = ring_buffer_num_items(&rx_buf);
  if (buf_len >= sizeof(tlv_head_t))
  {
		if( ring_buffer_peek(&rx_buf, &tmp, 0) )  // header
		{
			if(tmp != TLV_Delimiter)  // 丢弃数据，直到找到TLV界定符为止
			{
				ring_buffer_dequeue(&rx_buf, &tmp) ;
				return ;
			}
		}
		
		if( ring_buffer_peek(&rx_buf, &tmp, 1) )  // Length
		{
			if( buf_len < sizeof(tlv_head_t) + (uint8_t)tmp + 2 )  // 还没有接收到一个帧
			{
				return ;
			}
		}
		
		if( ring_buffer_dequeue_arr(&rx_buf, (char *)(&packet_head), sizeof(tlv_head_t)) == sizeof(tlv_head_t) )
		{
			// 回传解析的数据头部内容
			ring_buffer_queue(&tx_buf, packet_head.Length);
			ring_buffer_queue(&tx_buf, packet_head.Tag);
			
			if(packet_head.Tag == USER_TYPE_1)
			{
				if (ring_buffer_dequeue_arr(&rx_buf, (char *)(&RxUserdata), sizeof(userdata)) == sizeof(userdata))
				{
					// crc16校验
					ring_buffer_dequeue(&rx_buf, (char *)(&crc16_l));
					ring_buffer_dequeue(&rx_buf, (char *)(&crc16_h));
					crc16 = crc16_x25_check((uint8_t *)(&RxUserdata), sizeof(userdata));
					if( (crc16 & 0x00FF) !=  crc16_l && ((crc16 & 0xFF00) >> 8) !=  crc16_h )
						return ;
					// do something......
					// 回传解析的用户数据
					ring_buffer_queue(&tx_buf, RxUserdata.temperature);
					ring_buffer_queue(&tx_buf, RxUserdata.year);
					ring_buffer_queue(&tx_buf, RxUserdata.month);
					ring_buffer_queue(&tx_buf, RxUserdata.day);
					ring_buffer_queue(&tx_buf, RxUserdata.hour);
					ring_buffer_queue(&tx_buf, RxUserdata.minute);
				}
				else
				{
					// 丢弃CRC16
					ring_buffer_dequeue(&rx_buf, (char *)(&crc16_h));
					ring_buffer_dequeue(&rx_buf, (char *)(&crc16_l));
				}
			}
			
			if( !ring_buffer_is_empty(&tx_buf) )
				USART_IntConfig(HT_USART1,  USART_INT_TXC , ENABLE);
		}
  }

}

void testTLVsend()
{
	userdata data1 = {23, 2023, 10, 30, 9, 55};
	char TxBuf[100] = {0}; 
	int packet_len = 0;
	packet_len = tlv_packet((uint8_t *)TxBuf, 100, &data1, sizeof(data1), USER_TYPE_1);
	ring_buffer_queue_arr(&tx_buf, TxBuf, packet_len);
	if( !ring_buffer_is_empty(&tx_buf) )
		USART_IntConfig(HT_USART1,  USART_INT_TXC , ENABLE);
}

//-----------------------------------------------------------------------------
int main(void)
{
  GPIO_Configuration();
  USART1_Configuration();
	
	testTLVsend();
	
  while (1)
  {
    if(HT_CKCU->APBCCR1 & (1 << 4))
      WDT_Restart();
		UART_MainRoutine();
  }
}
